/*******************************************************************************
  * 文件：NetComm_Device.c
  * 作者：djy
  * 版本：v1.0.0
  * 日期：2017-08-03
  * 说明：设备相关
*******************************************************************************/
/* 头文件 *********************************************************************/
#include "NetComm_Device.h"
#include "NetComm_Cmd.h"
#include "NetComm_DeviceSet.h"
#include "StateMachine.h"
#include "DevInfor.h"
#include "DevError.h"
#include "Comfun.h"
#include "TimingCtrl.h"
#include <string.h>
#include "Hardware_IO.h"

/* 宏定义 *********************************************************************/
/* 类型定义 *******************************************************************/
/* 变量定义 *******************************************************************/
// 报警状态
NetCommAlarmStatus_tu uAlarmStatus;
NetCommAlarmStatus_tu uAlarmStatusBak;
// 设备状态
NetCommDevStatus_tu uDevStatus;
NetCommDevStatus_tu uDevStatusBak;

// 意外熄火和干烧报警，报警锁存
static Bool bLeftFireOffPosLatch  = 0;
static Bool bMidFireOffPosLatch   = 0;
static Bool bRightFireOffPosLatch = 0;
static Bool bLeftDryBurnPosLatch  = 0;

static const NetCommDevSetHandler_ts asDevSetHandlerTab[] =
{
    {U16_NETCOMM_CMD_01_SET_POWER,          "设备开关机",                  NetCommDevSetPower           },
//    {U16_NETCOMM_CMD_01_SET_LEFTFIRE,       "设置左灶火开关",              NetCommDevSetLeftStvFire     },
//    {U16_NETCOMM_CMD_01_SET_MIDFIRE,        "设置中灶火开关",              NetCommDevSetMidStvFire      },
//    {U16_NETCOMM_CMD_01_SET_RIGHTFIRE,      "设置右灶火开关",              NetCommDevSetRightStvFire    },
    {U16_NETCOMM_CMD_01_SET_LEFTTIMINGTIME, "设置左灶定时时间",            NetCommDevSetLeftTimingTime  },
    {U16_NETCOMM_CMD_01_SET_RIGHTTIMINGTIME,"设置右灶定时时间",            NetCommDevSetRightTimingTime },
    {U16_NETCOMM_CMD_01_SET_MIDTIMINGTIME,  "设置中灶定时时间",            NetCommDevSetMidTimingTime   },
};

/*******************************************************************************
  * 函数名: GetDevSetHandler
  * 功  能：获取设备设置
  * 参  数：U16 u16SetType - 设置类型
  * 返回值：const NetCommDevSetHandler_ts * 设置表中对应设置类型的设置指针
  * 说  明：无
*******************************************************************************/
static const NetCommDevSetHandler_ts * GetDevSetHandler(U16 u16SetType)
{
    int i;

    for(i=0; i<ARRAY_SIZE(asDevSetHandlerTab); i++)
    {
        if(u16SetType == asDevSetHandlerTab[i].u16SetType)
        {
            return (&asDevSetHandlerTab[i]);
        }
    }

    return NULL;
}
/*******************************************************************************
  * 函数名: NetComm_SetDevStatus
  * 功  能：设置设备状态
  * 参  数：U16 u16SetType - 设置类型
  *         U16 u16SetData - 设置数据
  * 返回值：0：不支持此设置类型   1：支持此设置类型
  * 说  明：无
*******************************************************************************/
int NetComm_SetDevStatus(U16 u16SetType, U16 u16SetData)
{
    const NetCommDevSetHandler_ts * psDevSet = GetDevSetHandler(u16SetType);

    if(psDevSet)
    {
        return (psDevSet->fun(u16SetData));
    }
    else
    {
        return 0;
    }
}

/*******************************************************************************
  * 函数名: NetComm_UpdataStatusData
  * 功  能：更新状态数据
  * 参  数：无
  * 返回值：无
  * 说  明：无
*******************************************************************************/
void NetComm_UpdataStatusData(void)
{
    //第一次运行标志位
    static U32 u32FirstUpdata = 0;
	
	// 设备电源状态，根据旋钮状态
	if(0 == Hardware_LeftStoveKnobCheck() 
	   	|| 0 == Hardware_MidStoveKnobCheck()
		  	|| 0 == Hardware_RightStoveKnobCheck())
	{
	  	uDevStatus.sDevStatus.u1DevPower = 1;
	}
	else
	{
	  	uDevStatus.sDevStatus.u1DevPower = 0;
	}
    //查询左灶是否开火
    if(eFIRE_ON == Dev_GetLeftFireState())
    {
        uDevStatus.sDevStatus.u1LeftFire = 1;
    }
    else
    {
        uDevStatus.sDevStatus.u1LeftFire = 0;
    }
    
    // 查询中灶是否开火
    if(eFIRE_ON == Dev_GetMidFireState())
    {
        uDevStatus.sDevStatus.u1MidFire = 1;
    }
    else
    {
        uDevStatus.sDevStatus.u1MidFire = 0;
    }

    // 查询右灶是否开火
    if(eFIRE_ON == Dev_GetRightFireState())
    {
        uDevStatus.sDevStatus.u1RightFire = 1;
    }
    else
    {
        uDevStatus.sDevStatus.u1RightFire = 0;
    }

    // 查询左灶定时是否在运行
    if(ON == Timing_CheckLeftTimingRun())
    {
        // 获取左灶定时时间
        uDevStatus.sDevStatus.u8LeftTimingTime = Timing_GetLeftTimingTime();
    }
    else
    {
        // 左灶定时时间为0
        uDevStatus.sDevStatus.u8LeftTimingTime = 0;
    }

    // 查询中灶定时是否在运行
    if(ON == Timing_CheckMidTimingRun())
    {
        // 获取中灶定时时间
        uDevStatus.sDevStatus.u8MidTimingTime = Timing_GetMidTimingTime();
    }
    else
    {
        // 中灶定时时间为0
        uDevStatus.sDevStatus.u8MidTimingTime = 0;
    }

    // 查询右灶定时是否在运行
    if(ON == Timing_CheckRightTimingRun())
    {
        // 获取右灶定时时间
        uDevStatus.sDevStatus.u8RightTimingTime = Timing_GetRightTimingTime();
    }
    else
    {
        // 中灶右时时间为0
        uDevStatus.sDevStatus.u8RightTimingTime = 0;
    }

  	// 旋钮开关状态根据实际硬件状态上报
  	if(0 == Hardware_LeftStoveKnobCheck())
	{
	  	uDevStatus.sDevStatus.u1LeftKnobStatus = 1;
	}
	else
	{
	  	uDevStatus.sDevStatus.u1LeftKnobStatus = 0;
	}
    
	if(0 == Hardware_MidStoveKnobCheck())
	{
		uDevStatus.sDevStatus.u1MidKnobStatus = 1;
	}
	else
	{
		uDevStatus.sDevStatus.u1MidKnobStatus = 0;
	}
	
	if(0 == Hardware_RightStoveKnobCheck())
	{
		uDevStatus.sDevStatus.u1RightKnobStatus = 1;
	}
	else
	{
	  	uDevStatus.sDevStatus.u1RightKnobStatus = 0;
	}
		
    // 更新右灶定时状态
    if(TRUE == Timing_CheckRightTimingExpire())
    {
        // 定时结束后的十秒内，认为定时完成
        uDevStatus.sDevStatus.u2RightTimingState = 2;
    }
    else
    {
        if(TRUE == Timing_CheckRightTimingRun())
        {
            // 定时运行中
            uDevStatus.sDevStatus.u2RightTimingState = 1;
        }
        else
        {
            // 定时关
            uDevStatus.sDevStatus.u2RightTimingState = 0;
        }
    }

    // 更新中灶定时状态
    if(TRUE == Timing_CheckMidTimingExpire())
    {
        // 定时结束后的十秒内，认为定时完成
        uDevStatus.sDevStatus.u2MidTimingState = 2;
    }
    else
    {
        if(TRUE == Timing_CheckMidTimingRun())
        {
            // 定时运行中
            uDevStatus.sDevStatus.u2MidTimingState = 1;
        }
        else
        {
            // 定时关
            uDevStatus.sDevStatus.u2MidTimingState = 0;
        }
    }
    
    // 更新左灶定时状态
    if(TRUE == Timing_CheckLeftTimingExpire())
    {
        // 定时结束后的十秒内，认为定时完成
        uDevStatus.sDevStatus.u2LeftTimingState = 2;
    }
    else
    {
        if(TRUE == Timing_CheckLeftTimingRun())
        {
            // 定时运行中
            uDevStatus.sDevStatus.u2LeftTimingState = 1;
        }
        else
        {
            // 定时关
            uDevStatus.sDevStatus.u2LeftTimingState = 0;
        }
    }
    
    // C6新型号默认为1
    uDevStatus.sDevStatus.u8SoftVer = 1;

    if(0 == u32FirstUpdata)
    {
        //第一次更新 备份
        u32FirstUpdata = 1;
        uDevStatusBak  = uDevStatus;
        uAlarmStatusBak = uAlarmStatus;
    }
}

/*******************************************************************************
  * 函数名: NetComm_UpdataAlarmStatusData
  * 功  能：更新报警数据
  * 参  数：无
  * 返回值：无
  * 说  明：无
*******************************************************************************/
void NetComm_UpdataAlarmStatusData(void)
{
	//第一次运行标志位
    static U32 u32FirstUpdata = 0;
	
	// 更新报警状态
    memset(&uAlarmStatus,0x00,sizeof(uAlarmStatus));
    
    if(eDEV_ERROR == StateMachine_GetCurState())
    {
        if(eERR_FLAMEOUT == Dev_GetErrorType())
        {
            // 意外熄火
            uAlarmStatus.sAlarmStatus.u8FireOff = 1;
        }
        else if(eERR_DRY_FIRE == Dev_GetErrorType())
        {   
            // 干烧
            uAlarmStatus.sAlarmStatus.u8DryBurn = 1;
        }
        else if(eERR_SENSOR == Dev_GetErrorType())
        {
            // 传感器故障
            uAlarmStatus.sAlarmStatus.u8Sensor = 1;
        }
        else if(eERR_FXQ == Dev_GetErrorType())
        {
            // 电磁阀故障，实际为副线圈故障
            uAlarmStatus.sAlarmStatus.u8DCF = 1;
        }
    }
	
	if(0 == u32FirstUpdata)
    {
        //第一次更新 备份
        u32FirstUpdata = 1;
        uAlarmStatusBak = uAlarmStatus;
    }
}

/*******************************************************************************
  * 函数名: NetComm_IsDevError
  * 功  能：检查是否故障
  * 参  数：无
  * 返回值：TRUE：故障，需要报警  FLASE:不故障，设备正常
  * 说  明：无
*******************************************************************************/
Bool NetComm_IsDevError(void)
{
    if(0 == uAlarmStatus.u8AlarmStatus[0] && 0 == uAlarmStatus.u8AlarmStatus[1])
    {
        return FALSE;
    }
    else
    {
        return TRUE;
    }
}

/*******************************************************************************
  * 函数名: NetComm_CheckAlarmStatus
  * 功  能：检查报警状态
  * 参  数：无
  * 返回值：设备状态是否改变
  * 说  明：无
*******************************************************************************/
Bool NetComm_CheckAlarmStatus(void)
{
    if(0 == memcmp(&uAlarmStatus,&uAlarmStatusBak,sizeof(uAlarmStatus)))
    {
        //报警信息未改变
        return FALSE;
    }
    else
    {
        //报警信息已改变         更新备份
        uAlarmStatusBak = uAlarmStatus;
        return TRUE;
    }
}

/*******************************************************************************
  * 函数名: NetComm_GetAlarmStatus
  * 功  能：获取报警状态
  * 参  数：U8* pu8Data - 数据指针
  * 返回值：数据长度
  * 说  明：无
*******************************************************************************/
U8 NetComm_GetAlarmStatus(U8* pu8Data)
{
    // 数据域复制
    memcpy(pu8Data,uAlarmStatus.u8AlarmStatus,sizeof(uAlarmStatus));
    // 返回长度
    return (sizeof(uAlarmStatus));
}

/*******************************************************************************
  * 函数名: NetComm_CheckDevStatus
  * 功  能：检查设备状态
  * 参  数：无
  * 返回值：设备状态是否改变
  * 说  明：无
*******************************************************************************/
Bool NetComm_CheckDevStatus(void)
{
    if(0 == memcmp(&uDevStatus,&uDevStatusBak,sizeof(uDevStatus)))
    {
        // 设备状态未改变
        return FALSE;
    }
    else
    {
        // 设备状态已改变         更新备份
        uDevStatusBak = uDevStatus;
        return TRUE;
    }
}

/*******************************************************************************
  * 函数名: NetComm_GetDevStatus
  * 功  能：获取设备状态
  * 参  数：U8* pu8Data - 数据指针
  * 返回值：数据长度
  * 说  明：无
*******************************************************************************/
U8 NetComm_GetDevStatus(U8* pu8Data)
{
    U8* pu8Byte = pu8Data;

    //设备状态赋值
    memcpy(pu8Byte,uDevStatus.u8DevStatus,sizeof(uDevStatus));

    return (sizeof(uDevStatus));
}

